﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Input;
using GlobalizationTools.UI;

namespace GlobalizationTools.ViewModel
{
    public class TreeViewItemViewModel : CommandViewModel
    {
        public static RoutedUICommandEx CloseCommand = new RoutedUICommandEx(LocalizationResource.Close, "Close", typeof(TreeViewItemViewModel), "/ViewModel/Images/Close.png", Key.C, ModifierKeys.Control);
        static readonly TreeViewItemViewModel DummyChild = new TreeViewItemViewModel();

        #region Data

        protected string _name;
        protected readonly ObservableCollection<TreeViewItemViewModel> _children = null;
        protected readonly TreeViewItemViewModel _parent = null;
        private readonly TreeViewRootViewModel _root = null;

        bool _isExpanded;
        bool _isSelected;

        #endregion Data

        protected TreeViewItemViewModel(bool hasChildren, bool lazyLoadChildren)
            : this()
        {
            if (hasChildren)
                _children = new ObservableCollection<TreeViewItemViewModel>();

            if (lazyLoadChildren)
                _children.Add(DummyChild);
        }

        protected TreeViewItemViewModel(TreeViewRootViewModel root, bool hasChildren, bool lazyLoadChildren)
            : this(hasChildren, lazyLoadChildren)
        {
            _root = root;
        }

        protected TreeViewItemViewModel(TreeViewItemViewModel parent, bool hasChildren, bool lazyLoadChildren)
            : this(hasChildren, lazyLoadChildren)
        {
            _parent = parent;
        }

        // This is used to create the DummyChild instance.
        private TreeViewItemViewModel()
        {
        }

        public override void AddCommandModels(List<CommandBinding> List)
        {
            List.Add(new CommandBinding(CloseCommand, ExecuteClose, CanExecuteClose));
        }

        public override void AddInputModels(List<InputBinding> List)
        {
        }

        #region Properties

        /// <summary>
        /// Returns true if this object's Children have not yet been populated.
        /// </summary>
        public bool HasDummyChild
        {
            get { return _children != null && this._children.Count == 1 && this._children[0] == DummyChild; }
        }

        /// <summary>
        /// Gets/sets whether the TreeViewItem 
        /// associated with this object is expanded.
        /// </summary>
        public bool IsExpanded
        {
            get { return _isExpanded; }
            set
            {
                if (value != _isExpanded)
                {
                    _isExpanded = value;
                    this.OnPropertyChanged("IsExpanded");
                }

                // Expand all the way up to the root.
                if (_isExpanded && _parent != null && Parent is TreeViewItemViewModel)
                    ((TreeViewItemViewModel)_parent).IsExpanded = true;

                // Lazy load the child items, if necessary.
                if (this.HasDummyChild)
                {
                    this._children.Remove(DummyChild);
                    this.LoadChildren();
                }
            }
        }

        /// <summary>
        /// Gets/sets whether the TreeViewItem 
        /// associated with this object is selected.
        /// </summary>
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (value != _isSelected)
                {
                    _isSelected = value;
                    this.OnPropertyChanged("IsSelected");
                }
            }
        }

        public string Name
        {
            get { return _name; }
        }

        public TreeViewItemViewModel Parent
        {
            get { return _parent; }
        }

        public TreeViewRootViewModel Root
        {
            get { return _root; }
        }

        /// <summary>
        /// Returns the logical child items of this object.
        /// </summary>
        public ObservableCollection<TreeViewItemViewModel> Children
        {
            get { return _children; }
        }

        #endregion Properties


        #region Functions

        /// <summary>
        /// Invoked when the child items need to be loaded on demand.
        /// Subclasses can override this to populate the Children collection.
        /// </summary>
        protected void LoadChildren()
        {
            try
            {
                Mouse.OverrideCursor = Cursors.Wait;
                this.StatusText = LocalizationResource.Loading;
                this.LoadChildrenInternal();
            }
            finally
            {
                this.StatusText = LocalizationResource.Ready;
                Mouse.OverrideCursor = null;
            }
        }

        protected virtual void LoadChildrenInternal()
        {
        }

        protected TreeViewRootViewModel FindRootModel()
        {
            TreeViewItemViewModel currentModel = this;
            while (currentModel._root == null && currentModel.Parent != null)
            {
                currentModel = currentModel._parent;
            }
            return currentModel._root;
        }

        #endregion Functions


        protected virtual void ExecuteClose(object sender, ExecutedRoutedEventArgs e)
        {
            if (this._root != null)
            {
                if (Close())
                {
                    _root.Children.Remove(this);
                }
            }
            e.Handled = true;
        }

        protected virtual void CanExecuteClose(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = this._root != null;
            e.Handled = true;
        }

        public virtual bool Close()
        {
            if (_children != null)
            {
                foreach (TreeViewItemViewModel model in _children)
                {
                    if (!model.Close())
                    {
                        return false;
                    }
                }
            }
            return true;
        }



    }
}
